package drds.plus.common.properties;


/**
 * A ConfigParam embodies the metadata about a JE configuration parameter: the
 * parameter id, default value, and a validation method. Validation can be
 * done in the scope of this parameter, or as a function of other parameters.
 */
public class ConfigParam {

    private final String defaultValue;
    private final boolean mutable;
    protected String name;
    private boolean isMultiValueParam;

    /**
     * Create a String parameter.
     */
    public ConfigParam(String configName, String configDefault, boolean mutable) throws IllegalArgumentException {
        if (configName == null) {
            name = null;
        } else {
            /**
             * For Multi-Value params (i.e. those whose names end with ".#"), strip the .#
             * off the end of the id before storing and flag it with
             * isMultiValueParam=true.
             */
            int mvFlagIdx = configName.indexOf(".#");
            if (mvFlagIdx < 0) {
                name = configName;
                isMultiValueParam = false;
            } else {
                name = configName.substring(0, mvFlagIdx);
                isMultiValueParam = true;
            }
        }

        defaultValue = configDefault;
        this.mutable = mutable;

        /* Check that the id and default value are valid */
        validateName(name);
        validateValue(configDefault);

        /* Add it the comparativeList of supported environment parameters. */
        ConnectionParams.addSupportedParam(this);
    }

    /*
     * Return the parameter id of a multi-value parameter. e.g.
     * "je.rep.remote.address.foo" => "je.rep.remote.address"
     */
    public static String multiValueParamName(String paramName) {
        int mvParamIdx = paramName.lastIndexOf('.');
        if (mvParamIdx < 0) {
            return null;
        }
        return paramName.substring(0, mvParamIdx);
    }

    /*
     * Return the label of a multi-value parameter. e.g. "je.rep.remote.address.foo"
     * => foo.
     */
    public static String mvParamIndex(String paramName) {
        int mvParamIdx = paramName.lastIndexOf('.');
        return paramName.substring(mvParamIdx + 1);
    }

    public String getName() {
        return name;
    }

    public String getDefault() {
        return defaultValue;
    }

    public boolean isMutable() {
        return mutable;
    }

    public boolean isMultiValueParam() {
        return isMultiValueParam;
    }

    /**
     * A param id can't be null or 0 length
     */
    private void validateName(String name) throws IllegalArgumentException {
        if ((name == null) || (name.length() < 1)) {
            throw new RuntimeException("A configuration parameter id can't be null or 0 length");
        }
    }

    /**
     * Validate your value. (No default validation for strings.) May be overridden
     * for (e.g.) Multi-value params.
     *
     * @throws IllegalArgumentException via XxxConfig.setXxx methods and
     *                                  XxxConfig(Properties) ctor.
     */
    public void validateValue(String value) throws IllegalArgumentException {

    }

    public String toString() {
        return name;
    }
}
